using System.Collections;
using System.Windows;
using System.Windows.Controls;

namespace FU.Capstones.IMS.Web.Common.AttachedProperties
{
    public static class ListBoxHelper
    {
        private static readonly DependencyProperty SelectedItemsBehaviorProperty =
            DependencyProperty.RegisterAttached(
                "SelectedItemsBehavior",
                typeof(SelectedItemsBehavior),
                typeof(ListBoxHelper),
                null);

        public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.RegisterAttached(
                "SelectedItems",
                typeof(IList),
                typeof(ListBoxHelper),
                new PropertyMetadata(null, ItemsPropertyChanged));

        public static void SetSelectedItems(ListBox listBox, IList list)
        {
            listBox.SetValue(SelectedItemsProperty, list);
        }

        public static IList GetSelectedItems(ListBox listBox)
        {
            return listBox.GetValue(SelectedItemsProperty) as IList;
        }

        private static void ItemsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var target = d as ListBox;
            if (target != null)
            {
                GetOrCreateBehavior(target, e.NewValue as IList);
            }
        }

        private static SelectedItemsBehavior GetOrCreateBehavior(ListBox target, IList list)
        {
            var behavior = target.GetValue(SelectedItemsBehaviorProperty) as SelectedItemsBehavior;
            if (behavior == null)
            {
                behavior = new SelectedItemsBehavior(target, list);
                target.SetValue(SelectedItemsBehaviorProperty, behavior);
            }

            return behavior;
        }
    }

    public class SelectedItemsBehavior
    {
        private readonly ListBox listBox;
        private readonly IList boundList;

        public SelectedItemsBehavior(ListBox listBox, IList boundList)
        {
            this.boundList = boundList;
            this.listBox = listBox;

            SetSelectedItems();

            this.listBox.SelectionChanged += OnSelectionChanged;
        }

        private void SetSelectedItems()
        {
            listBox.SelectedItems.Clear();

            foreach (object item in boundList)
            {
                // References in _boundList might not be the same as in _listBox.Items
                int i = listBox.Items.IndexOf(item);
                if (i >= 0)
                    listBox.SelectedItems.Add(listBox.Items[i]);
            }
        }

        private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            boundList.Clear();

            foreach (var item in listBox.SelectedItems)
            {
                boundList.Add(item);
            }
        }
    }

}